<template>
  <div class="rbo-workflow-designer-v2" :class="{ fullscreen: isFullscreen }">
    <div class="designer-header">
      <h3>RBO工作流设计器 v2</h3>
      <div class="header-actions">
        <Button @click="toggleFullscreen" type="default">
          <IconifyIcon
            :icon="
              isFullscreen
                ? 'ant-design:fullscreen-exit-outlined'
                : 'ant-design:fullscreen-outlined'
            "
          />
          {{ isFullscreen ? '退出全屏' : '全屏' }}
        </Button>
        <Button @click="saveWorkflow" type="primary">
          <IconifyIcon icon="ant-design:save-outlined" />
          保存工作流
        </Button>
        <Button @click="exportWorkflow" type="default">
          <IconifyIcon icon="ant-design:export-outlined" />
          导出
        </Button>
        <Button @click="testWorkflow" type="default">
          <IconifyIcon icon="ant-design:play-circle-outlined" />
          测试
        </Button>
      </div>
    </div>

    <div class="designer-content">
      <div
        ref="tinyflowContainer"
        class="rbo-workflow-canvas h-full w-full"
      ></div>
    </div>

    <!-- 测试抽屉 -->
    <Drawer v-model:open="testDrawerVisible" title="工作流测试" width="600">
      <div class="test-content">
        <div class="test-section">
          <h4>测试参数</h4>
          <div class="param-list">
            <div
              v-for="(param, index) in testParams"
              :key="index"
              class="param-item"
            >
              <Input
                v-model:value="param.key"
                placeholder="参数名"
                class="param-key"
              />
              <Input
                v-model:value="param.value"
                placeholder="参数值"
                class="param-value"
              />
              <Button
                type="text"
                danger
                @click="removeTestParam(index)"
                class="param-remove"
              >
                <IconifyIcon icon="ant-design:delete-outlined" />
              </Button>
            </div>
          </div>
          <Button type="dashed" @click="addTestParam" class="add-param-btn">
            <IconifyIcon icon="ant-design:plus-outlined" />
            添加参数
          </Button>
        </div>

        <div class="test-section">
          <h4>执行结果</h4>
          <div class="result-content">
            <div v-if="testLoading" class="loading">
              <IconifyIcon icon="ant-design:loading-outlined" spin />
              执行中...
            </div>
            <div v-else-if="testError" class="error">
              {{ testError }}
            </div>
            <pre v-else-if="testResult" class="result-json">
              {{ JSON.stringify(testResult, null, 2) }}
            </pre>
            <div v-else class="no-result">点击运行查看结果</div>
          </div>
        </div>

        <Button
          type="primary"
          size="large"
          :loading="testLoading"
          @click="executeWorkflow"
          class="execute-btn"
        >
          执行工作流
        </Button>
      </div>
    </Drawer>
  </div>
</template>

<script lang="ts" setup>
import { ref, reactive, onMounted, onUnmounted } from 'vue';
import { Button, Input, message } from 'ant-design-vue';
import { IconifyIcon } from '@vben/icons';
import { Tinyflow } from '@tinyflow-ai/ui';
import '@tinyflow-ai/ui/dist/index.css';
import { useVbenDrawer } from '@vben/common-ui';

// 全屏状态
const isFullscreen = ref(false);

// 定义RBO节点类型
interface RboNode {
  id: string;
  type: string;
  label: string;
  icon: string;
  config: Record<string, any>;
}

// 定义RBO连接类型
interface RboConnection {
  id: string;
  from: string;
  to: string;
  label?: string;
}

// 响应式数据
const tinyflowContainer = ref<HTMLElement>();
let tinyflowInstance: any = null;
const workflowData = ref({
  nodes: [],
  edges: [],
  viewport: { x: 0, y: 0, zoom: 1 },
});

// 测试相关
const testDrawerVisible = ref(false);
const testParams = ref<Array<{ key: string; value: string }>>([]);
const testLoading = ref(false);
const testResult = ref(null);
const testError = ref('');

const [Drawer] = useVbenDrawer();

// RBO Provider - 提供节点类型
const rboProvider = {
  // 内部节点类型
  internal: () => [
    {
      value: 'behavior_execute',
      label: '行为执行',
      icon: 'ant-design:play-circle-outlined',
    },
    {
      value: 'service_call',
      label: '服务调用',
      icon: 'ant-design:api-outlined',
    },
    {
      value: 'workflow_sub',
      label: '子工作流',
      icon: 'ant-design:branches-outlined',
    },
    {
      value: 'rule_engine',
      label: '规则引擎',
      icon: 'ant-design:code-outlined',
    },
    {
      value: 'condition',
      label: '条件判断',
      icon: 'ant-design:question-circle-outlined',
    },
    {
      value: 'parallel',
      label: '并行执行',
      icon: 'ant-design:fork-outlined',
    },
    {
      value: 'loop',
      label: '循环执行',
      icon: 'ant-design:reload-outlined',
    },
    {
      value: 'delay',
      label: '延时等待',
      icon: 'ant-design:clock-circle-outlined',
    },
    {
      value: 'event_publish',
      label: '事件发布',
      icon: 'ant-design:notification-outlined',
    },
    {
      value: 'event_listen',
      label: '事件监听',
      icon: 'ant-design:ear-outlined',
    },
    {
      value: 'message_send',
      label: '消息发送',
      icon: 'ant-design:message-outlined',
    },
    {
      value: 'message_receive',
      label: '消息接收',
      icon: 'ant-design:inbox-outlined',
    },
    {
      value: 'data_transform',
      label: '数据转换',
      icon: 'ant-design:swap-outlined',
    },
    {
      value: 'data_filter',
      label: '数据过滤',
      icon: 'ant-design:filter-outlined',
    },
    {
      value: 'data_aggregate',
      label: '数据聚合',
      icon: 'ant-design:cluster-outlined',
    },
    {
      value: 'data_validate',
      label: '数据验证',
      icon: 'ant-design:check-circle-outlined',
    },
  ],
  // 知识库节点类型
  knowledge: () => [
    {
      value: 'knowledge_query',
      label: '知识查询',
      icon: 'ant-design:search-outlined',
    },
    {
      value: 'knowledge_update',
      label: '知识更新',
      icon: 'ant-design:edit-outlined',
    },
    {
      value: 'knowledge_embed',
      label: '知识嵌入',
      icon: 'ant-design:link-outlined',
    },
  ],
  // LLM节点类型
  llm: () => [
    {
      value: 'llm_chat',
      label: 'LLM对话',
      icon: 'ant-design:message-outlined',
    },
    {
      value: 'llm_generate',
      label: 'LLM生成',
      icon: 'ant-design:bulb-outlined',
    },
    {
      value: 'llm_analyze',
      label: 'LLM分析',
      icon: 'ant-design:fund-outlined',
    },
  ],
};

// RBO 自定义节点配置
const rboCustomNodes = {
  // 酒店预订节点
  'hotel-booking': {
    title: '酒店预订',
    description: '处理酒店房间预订业务',
    icon: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M20 20C20 20.5523 19.5523 21 19 21H5C4.44772 21 4 20.5523 4 20V11H1L11.3273 1.6115C11.7087 1.26475 12.2913 1.26475 12.6727 1.6115L23 11H20V20ZM18 19V9.15745L12 3.7029L6 9.15745V19H18ZM12 17L8.64124 13.6412C7.76256 12.7625 7.76256 11.3379 8.64124 10.4592C9.51992 9.58056 10.9445 9.58056 11.8232 10.4592L12 10.636L12.1768 10.4592C13.0555 9.58056 14.4801 9.58056 15.3588 10.4592C16.2374 11.3379 16.2374 12.7625 15.3588 13.6412L12 17Z"></path></svg>',
    sortNo: 1,
    group: 'base',
    render: (parent, node, flowInstance) => {
      parent.innerHTML = `
        <div style="padding: 8px;">
          <div style="margin-bottom: 8px;">
            <label style="display: block; margin-bottom: 4px; font-weight: bold;">预订类型:</label>
            <select style="width: 100%; padding: 4px; border: 1px solid #d9d9d9; border-radius: 4px;">
              <option value="standard">标准预订</option>
              <option value="vip">VIP预订</option>
              <option value="group">团体预订</option>
            </select>
          </div>
          <div style="margin-bottom: 8px;">
            <label style="display: block; margin-bottom: 4px; font-weight: bold;">房间类型:</label>
            <select style="width: 100%; padding: 4px; border: 1px solid #d9d9d9; border-radius: 4px;">
              <option value="single">单人间</option>
              <option value="double">双人间</option>
              <option value="suite">套房</option>
            </select>
          </div>
          <div>
            <label style="display: block; margin-bottom: 4px; font-weight: bold;">入住天数:</label>
            <input type="number" min="1" value="1" style="width: 100%; padding: 4px; border: 1px solid #d9d9d9; border-radius: 4px;">
          </div>
        </div>
      `;

      // 添加事件监听
      const selects = parent.querySelectorAll('select');
      const input = parent.querySelector('input');

      selects.forEach((select) => {
        select.addEventListener('change', (e) => {
          const target = e.target as HTMLSelectElement;
          flowInstance.updateNodeData(node.id, {
            bookingType: target.value,
            roomType: selects[1].value,
            days: input?.value || 1,
          });
        });
      });

      input?.addEventListener('change', (e) => {
        const target = e.target as HTMLInputElement;
        flowInstance.updateNodeData(node.id, {
          bookingType: selects[0].value,
          roomType: selects[1].value,
          days: target.value,
        });
      });
    },
    onUpdate: (parent, node) => {
      console.log('酒店预订节点更新:', node);
    },
  },

  // 支付处理节点
  'payment-process': {
    title: '支付处理',
    description: '处理各种支付方式',
    icon: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M4 4H20C21.1 4 22 4.9 22 6V18C22 19.1 21.1 20 20 20H4C2.9 20 2 19.1 2 18V6C2 4.9 2.9 4 4 4ZM4 6V18H20V6H4ZM6 8H18V10H6V8ZM6 12H14V14H6V12Z"></path></svg>',
    sortNo: 2,
    group: 'base',
    render: (parent, node, flowInstance) => {
      parent.innerHTML = `
        <div style="padding: 8px;">
          <div style="margin-bottom: 8px;">
            <label style="display: block; margin-bottom: 4px; font-weight: bold;">支付方式:</label>
            <select style="width: 100%; padding: 4px; border: 1px solid #d9d9d9; border-radius: 4px;">
              <option value="credit">信用卡</option>
              <option value="debit">借记卡</option>
              <option value="alipay">支付宝</option>
              <option value="wechat">微信支付</option>
              <option value="cash">现金</option>
            </select>
          </div>
          <div style="margin-bottom: 8px;">
            <label style="display: block; margin-bottom: 4px; font-weight: bold;">支付金额:</label>
            <input type="number" min="0" step="0.01" placeholder="0.00" style="width: 100%; padding: 4px; border: 1px solid #d9d9d9; border-radius: 4px;">
          </div>
          <div>
            <label style="display: block; margin-bottom: 4px; font-weight: bold;">自动确认:</label>
            <input type="checkbox" style="margin-right: 4px;">
            <span style="font-size: 12px;">支付成功后自动确认</span>
          </div>
        </div>
      `;

      const select = parent.querySelector('select');
      const input = parent.querySelector('input[type="number"]');
      const checkbox = parent.querySelector('input[type="checkbox"]');

      select?.addEventListener('change', (e) => {
        const target = e.target as HTMLSelectElement;
        flowInstance.updateNodeData(node.id, {
          paymentMethod: target.value,
          amount: input?.value || 0,
          autoConfirm: checkbox?.checked || false,
        });
      });

      input?.addEventListener('change', (e) => {
        const target = e.target as HTMLInputElement;
        flowInstance.updateNodeData(node.id, {
          paymentMethod: select?.value || 'credit',
          amount: target.value,
          autoConfirm: checkbox?.checked || false,
        });
      });

      checkbox?.addEventListener('change', (e) => {
        const target = e.target as HTMLInputElement;
        flowInstance.updateNodeData(node.id, {
          paymentMethod: select?.value || 'credit',
          amount: input?.value || 0,
          autoConfirm: target.checked,
        });
      });
    },
    onUpdate: (parent, node) => {
      console.log('支付处理节点更新:', node);
    },
  },

  // 客户服务节点
  'customer-service': {
    title: '客户服务',
    description: '处理客户咨询和投诉',
    icon: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M12 2C13.1 2 14 2.9 14 4C14 5.1 13.1 6 12 6C10.9 6 10 5.1 10 4C10 2.9 10.9 2 12 2ZM21 9V7L15 1H5C3.9 1 3 1.9 3 3V21C3 22.1 3.9 23 5 23H19C20.1 23 21 22.1 21 21V9ZM19 21H5V3H13V9H19V21Z"></path></svg>',
    sortNo: 3,
    group: 'base',
    render: (parent, node, flowInstance) => {
      parent.innerHTML = `
        <div style="padding: 8px;">
          <div style="margin-bottom: 8px;">
            <label style="display: block; margin-bottom: 4px; font-weight: bold;">服务类型:</label>
            <select style="width: 100%; padding: 4px; border: 1px solid #d9d9d9; border-radius: 4px;">
              <option value="consultation">咨询</option>
              <option value="complaint">投诉</option>
              <option value="suggestion">建议</option>
              <option value="emergency">紧急情况</option>
            </select>
          </div>
          <div style="margin-bottom: 8px;">
            <label style="display: block; margin-bottom: 4px; font-weight: bold;">优先级:</label>
            <select style="width: 100%; padding: 4px; border: 1px solid #d9d9d9; border-radius: 4px;">
              <option value="low">低</option>
              <option value="medium">中</option>
              <option value="high">高</option>
              <option value="urgent">紧急</option>
            </select>
          </div>
          <div>
            <label style="display: block; margin-bottom: 4px; font-weight: bold;">自动回复:</label>
            <textarea placeholder="请输入自动回复内容..." style="width: 100%; height: 60px; padding: 4px; border: 1px solid #d9d9d9; border-radius: 4px; resize: vertical;"></textarea>
          </div>
        </div>
      `;

      const typeSelect = parent.querySelector('select:first-of-type');
      const prioritySelect = parent.querySelector('select:last-of-type');
      const textarea = parent.querySelector('textarea');

      const updateData = () => {
        flowInstance.updateNodeData(node.id, {
          serviceType: typeSelect?.value || 'consultation',
          priority: prioritySelect?.value || 'medium',
          autoReply: textarea?.value || '',
        });
      };

      typeSelect?.addEventListener('change', updateData);
      prioritySelect?.addEventListener('change', updateData);
      textarea?.addEventListener('input', updateData);
    },
    onUpdate: (parent, node) => {
      console.log('客户服务节点更新:', node);
    },
  },

  // 库存管理节点
  'inventory-management': {
    title: '库存管理',
    description: '管理酒店房间和设施库存',
    icon: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M20 2H4C2.9 2 2 2.9 2 4V22L6 18H20C21.1 18 22 17.1 22 16V4C22 2.9 21.1 2 20 2ZM20 16H6L4 18V4H20V16Z"></path></svg>',
    sortNo: 4,
    group: 'tools',
    render: (parent, node, flowInstance) => {
      parent.innerHTML = `
        <div style="padding: 8px;">
          <div style="margin-bottom: 8px;">
            <label style="display: block; margin-bottom: 4px; font-weight: bold;">库存类型:</label>
            <select style="width: 100%; padding: 4px; border: 1px solid #d9d9d9; border-radius: 4px;">
              <option value="rooms">房间</option>
              <option value="facilities">设施</option>
              <option value="supplies">用品</option>
              <option value="food">餐饮</option>
            </select>
          </div>
          <div style="margin-bottom: 8px;">
            <label style="display: block; margin-bottom: 4px; font-weight: bold;">操作类型:</label>
            <select style="width: 100%; padding: 4px; border: 1px solid #d9d9d9; border-radius: 4px;">
              <option value="check">检查库存</option>
              <option value="reserve">预订库存</option>
              <option value="release">释放库存</option>
              <option value="update">更新库存</option>
            </select>
          </div>
          <div>
            <label style="display: block; margin-bottom: 4px; font-weight: bold;">数量:</label>
            <input type="number" min="0" value="1" style="width: 100%; padding: 4px; border: 1px solid #d9d9d9; border-radius: 4px;">
          </div>
        </div>
      `;

      const typeSelect = parent.querySelector('select:first-of-type');
      const actionSelect = parent.querySelector('select:last-of-type');
      const input = parent.querySelector('input');

      const updateData = () => {
        flowInstance.updateNodeData(node.id, {
          inventoryType: typeSelect?.value || 'rooms',
          actionType: actionSelect?.value || 'check',
          quantity: input?.value || 1,
        });
      };

      typeSelect?.addEventListener('change', updateData);
      actionSelect?.addEventListener('change', updateData);
      input?.addEventListener('change', updateData);
    },
    onUpdate: (parent, node) => {
      console.log('库存管理节点更新:', node);
    },
  },

  // 数据分析节点
  'data-analysis': {
    title: '数据分析',
    description: '分析业务数据和生成报告',
    icon: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M3 13H7V23H3V13ZM10 9H14V23H10V9ZM17 5H21V23H17V5ZM2 11H6V13H2V11ZM9 7H13V9H9V7ZM16 3H20V5H16V3Z"></path></svg>',
    sortNo: 5,
    group: 'tools',
    render: (parent, node, flowInstance) => {
      parent.innerHTML = `
        <div style="padding: 8px;">
          <div style="margin-bottom: 8px;">
            <label style="display: block; margin-bottom: 4px; font-weight: bold;">分析类型:</label>
            <select style="width: 100%; padding: 4px; border: 1px solid #d9d9d9; border-radius: 4px;">
              <option value="revenue">收入分析</option>
              <option value="occupancy">入住率分析</option>
              <option value="customer">客户分析</option>
              <option value="performance">绩效分析</option>
            </select>
          </div>
          <div style="margin-bottom: 8px;">
            <label style="display: block; margin-bottom: 4px; font-weight: bold;">时间范围:</label>
            <select style="width: 100%; padding: 4px; border: 1px solid #d9d9d9; border-radius: 4px;">
              <option value="daily">日报</option>
              <option value="weekly">周报</option>
              <option value="monthly">月报</option>
              <option value="quarterly">季报</option>
            </select>
          </div>
          <div>
            <label style="display: block; margin-bottom: 4px; font-weight: bold;">输出格式:</label>
            <select style="width: 100%; padding: 4px; border: 1px solid #d9d9d9; border-radius: 4px;">
              <option value="json">JSON</option>
              <option value="csv">CSV</option>
              <option value="excel">Excel</option>
              <option value="pdf">PDF</option>
            </select>
          </div>
        </div>
      `;

      const analysisSelect = parent.querySelector('select:nth-of-type(1)');
      const timeSelect = parent.querySelector('select:nth-of-type(2)');
      const formatSelect = parent.querySelector('select:nth-of-type(3)');

      const updateData = () => {
        flowInstance.updateNodeData(node.id, {
          analysisType: analysisSelect?.value || 'revenue',
          timeRange: timeSelect?.value || 'daily',
          outputFormat: formatSelect?.value || 'json',
        });
      };

      analysisSelect?.addEventListener('change', updateData);
      timeSelect?.addEventListener('change', updateData);
      formatSelect?.addEventListener('change', updateData);
    },
    onUpdate: (parent, node) => {
      console.log('数据分析节点更新:', node);
    },
  },
};

// 工作流操作
// 全屏切换
const toggleFullscreen = () => {
  isFullscreen.value = !isFullscreen.value;
  if (isFullscreen.value) {
    document.body.style.overflow = 'hidden';
  } else {
    document.body.style.overflow = '';
  }
};

// 初始化Tinyflow
onMounted(() => {
  if (tinyflowContainer.value) {
    console.log('初始化Tinyflow...');
    console.log('RBO Provider配置:', rboProvider);
    console.log('RBO Custom Nodes配置:', rboCustomNodes);

    tinyflowInstance = new Tinyflow({
      element: tinyflowContainer.value,
      data: workflowData.value,
      provider: rboProvider,
      customNodes: rboCustomNodes,
    });

    console.log('Tinyflow实例:', tinyflowInstance);
  }
});

// 销毁Tinyflow
onUnmounted(() => {
  if (tinyflowInstance) {
    tinyflowInstance.destroy();
    tinyflowInstance = null;
  }
});

const saveWorkflow = () => {
  try {
    const data = tinyflowInstance?.getData();
    if (data) {
      workflowData.value = data;
      console.log('保存工作流:', data);
      message.success('工作流保存成功');
    }
  } catch (error) {
    console.error('保存工作流失败:', error);
    message.error('保存工作流失败');
  }
};

const exportWorkflow = () => {
  try {
    const data = tinyflowInstance?.getData();
    if (data) {
      const dataStr = JSON.stringify(data, null, 2);
      const dataBlob = new Blob([dataStr], { type: 'application/json' });
      const url = URL.createObjectURL(dataBlob);

      const link = document.createElement('a');
      link.href = url;
      link.download = 'rbo-workflow.json';
      link.click();

      URL.revokeObjectURL(url);
      message.success('工作流导出成功');
    }
  } catch (error) {
    console.error('导出工作流失败:', error);
    message.error('导出工作流失败');
  }
};

const testWorkflow = () => {
  testDrawerVisible.value = true;
  testParams.value = [];
  testResult.value = null;
  testError.value = '';
};

const addTestParam = () => {
  testParams.value.push({ key: '', value: '' });
};

const removeTestParam = (index: number) => {
  testParams.value.splice(index, 1);
};

const executeWorkflow = async () => {
  try {
    testLoading.value = true;
    testError.value = '';
    testResult.value = null;

    const data = tinyflowInstance?.getData();
    if (!data || !data.nodes || data.nodes.length === 0) {
      throw new Error('请先设计工作流');
    }

    // 构建测试参数
    const params: Record<string, any> = {};
    testParams.value.forEach((param) => {
      if (param.key.trim()) {
        params[param.key.trim()] = param.value;
      }
    });

    // 模拟工作流执行
    await new Promise((resolve) => setTimeout(resolve, 2000));

    // 模拟执行结果
    testResult.value = {
      success: true,
      executionTime: '2.1s',
      steps: data.nodes.map((node: any) => ({
        id: node.id,
        type: node.type,
        status: 'completed',
        result: `执行${node.data?.label || node.type}成功`,
      })),
      output: {
        message: '工作流执行完成',
        data: params,
      },
    };

    message.success('工作流执行成功');
  } catch (error: any) {
    testError.value = error.message || '执行失败';
    message.error('工作流执行失败');
  } finally {
    testLoading.value = false;
  }
};

// 初始化
onMounted(() => {
  // 可以在这里加载已有的工作流数据
  console.log('RBO工作流设计器v2初始化完成');
});

// 暴露方法给父组件
defineExpose({
  getData: () => {
    return tinyflowInstance?.getData();
  },
});
</script>

<style lang="less" scoped>
.rbo-workflow-designer-v2 {
  height: 100%;
  display: flex;
  flex-direction: column;
  transition: all 0.3s ease;

  &.fullscreen {
    position: fixed;
    top: 0;
    left: 0;
    width: 100vw;
    height: 100vh;
    z-index: 9999;
    background: #fff;
  }

  .designer-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 16px;
    border-bottom: 1px solid #f0f0f0;
    background: #fff;

    h3 {
      margin: 0;
      color: #1890ff;
    }

    .header-actions {
      display: flex;
      gap: 8px;
    }
  }

  .designer-content {
    flex: 1;
    overflow: hidden;
    background: #fafafa;

    .rbo-workflow-canvas {
      height: 100%;
      border: 1px solid #e8e8e8;
      border-radius: 4px;
    }
  }

  .test-content {
    .test-section {
      margin-bottom: 24px;

      h4 {
        margin-bottom: 12px;
        color: #333;
        font-weight: 500;
      }

      .param-list {
        .param-item {
          display: flex;
          gap: 8px;
          margin-bottom: 8px;
          align-items: center;

          .param-key {
            flex: 1;
          }

          .param-value {
            flex: 1;
          }

          .param-remove {
            flex-shrink: 0;
          }
        }
      }

      .add-param-btn {
        width: 100%;
        margin-top: 8px;
      }

      .result-content {
        min-height: 200px;
        border: 1px solid #d9d9d9;
        border-radius: 4px;
        padding: 12px;
        background: #fafafa;

        .loading {
          display: flex;
          align-items: center;
          gap: 8px;
          color: #1890ff;
        }

        .error {
          color: #ff4d4f;
        }

        .result-json {
          background: #fff;
          border: 1px solid #d9d9d9;
          border-radius: 4px;
          padding: 12px;
          font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
          font-size: 12px;
          line-height: 1.5;
          max-height: 300px;
          overflow: auto;
          white-space: pre-wrap;
        }

        .no-result {
          color: #999;
          text-align: center;
          padding: 40px 0;
        }
      }
    }

    .execute-btn {
      width: 100%;
      margin-top: 16px;
    }
  }
}
.tinyflow-logo:after {
  content: 'Xaas';
}
</style>
